<template>
  <container-item-wrapper :widget="widget">

    <div :class="['sub-form-container', disabledClass, readModeClass, customClass]" @click.stop
      v-show="!widget.options.hidden">
      <el-row class="options-row" v-if="!isReadMode && !widget.options.isHideActionBar">
        <el-button v-if="widget.options.morePermissions.handleAdd" @click="addSubFormRow"><el-icon>
            <Plus />
          </el-icon>新建</el-button>
        <el-button v-if="widget.options.morePermissions.handleCopy" @click="copySubFormRow(currentIndex)"><el-icon>
            <DocumentCopy />
          </el-icon>复制</el-button>
        <!-- <el-button v-if="widget.options.morePermissions.handleDeleteAll" -->
        <el-button v-if="widget.options.morePermissions.handleDeleteRow"
          @click="deleteSubFormRow(currentIndex)"><el-icon>
            <Delete />
          </el-icon>删除</el-button>
        <!-- <el-button v-if="widget.options.morePermissions.handleDeleteRow" @click="delAllSubFormRow"><el-icon> -->
        <el-button v-if="widget.options.morePermissions.handleDeleteAll" @click="delAllSubFormRow"><el-icon>
            <Delete />
          </el-icon>删除全部</el-button>
        <!-- <el-button v-if="widget.options.morePermissions.handleExport" @click=""><el-icon> -->
        <el-button v-if="widget.options.morePermissions.handleImport" @click="onclickBatchImport"><el-icon>
            <Upload />
          </el-icon>导入数据</el-button>
        <!-- <el-button v-if="widget.options.morePermissions.handleImport" @click="exportSubForm"><el-icon> -->
        <el-button v-if="widget.options.morePermissions.handleExport" @click="onclickBatchExport"><el-icon>
            <Download />
          </el-icon>导出数据</el-button>
        <el-button v-if="widget.options.isBatchPadding" @click="batchPaddingHandle"><el-icon>
            <Plus />
          </el-icon>批量添加</el-button>
        <el-button v-if="widget.hasDataMapping" @click.stop="openDataMappingDialog($event, widget)">
          <span title="数据对应关系关联">
            <svg-icon :icon-class="widget.mappingIcon" :size="16" color="#2E5CF6" />
          </span>
        </el-button>

        <ZHLXCommonSelect ref="zhlxCommonSelectRef" v-if="widget.options.isBatchPadding" title="批量添加"
          :model-value="selectedAuditor" isReturnData :authorityList="[]" choosePerson="person" :multiple="true"
          :showInput="false" @change="handleSelectedAuditorChange" />
      </el-row>
      <el-row class="header-row" :class='widget.options.isRowWidth100 ? "isRowWidth100" : ""'
        :style="{ 'height': widget.options.labelHeight + 'px', 'font-size': widget.options.fontSize + 'px', 'background': widget.options.labelBackgroundColor + ' !important', 'font-family': widget.options.fontFamily, 'color': widget.options.fontColor, 'font-weight': widget.options.fontBlod ? 'bold' : '' }">
        <div class="row-no-header-column" :style="{ 'background': widget.options.labelBackgroundColor + ' !important', 'width': widget.options.numColumnWidth }"
          v-if="widget.options.showNumColumn">
          <span>序号</span>
        </div>
        <!-- 表头操作按钮 -->
        <!-- <div v-if="leftActionColumn" class="action-header-column">
          <span class="action-label">{{i18nt('render.hint.subFormAction')}}</span>
          <el-button v-if="!isReadMode" :disabled="widgetDisabled || actionDisabled || insertDisabled"
                     round type="primary" size="small"
                     class="action-button" @click="addSubFormRow" :title="i18nt('render.hint.subFormAddActionHint')">
            {{i18nt('render.hint.subFormAddAction')}}<svg-icon icon-class="el-plus" /></el-button>
        </div>
        <div v-if="!leftActionColumn && widget.options.showNumColumn" class="row-no-header-column">
          <span>{{i18nt('render.hint.subFormRowNo')}}</span>
        </div> -->
        <template v-for="(subWidget, index) in widget.widgetList" :key="subWidget.id + 'thc'">
          <div v-if="!subWidget.options.hidden" class="field-header-column"
            :class="[getLabelAlign(widget, subWidget), !!subWidget.options.required ? 'is-required' : '', index === widget.widgetList.length - 1 ? '' : 'no-border-right']"
            :style="{ width: subWidget.options.columnWidth, 'background': widget.options.labelBackgroundColor + ' !important', 'line-height': subWidget.options.comStyle.labelLineHeight }">
            <!-- 设置最小宽度 -->
            <!-- :style="'width: ' + subWidget.options.columnWidth + ' !important;' + (subWidget.options.columnWidth || subWidget.options.columnMinWidth ? '' : 'flex:1;') + (subWidget.options.columnMinWidth ? 'min-width:' + subWidget.options.columnMinWidth + ' !important' : '')"> -->
            <span v-if="!!subWidget.options.labelIconClass" class="custom-label">
              <template v-if="subWidget.options.labelIconPosition === 'front'">
                <template v-if="!!subWidget.options.labelTooltip">
                  <el-tooltip :content="subWidget.options.labelTooltip" effect="light">
                    <el-icon><component :is="subWidget.options.labelIconClass" /></el-icon></el-tooltip>{{subWidget.options.label}}</template>
                <template v-else>
                  <el-icon><component :is="subWidget.options.labelIconClass" /></el-icon>{{subWidget.options.label}}</template>
              </template>
              <template v-else-if="subWidget.options.labelIconPosition === 'rear'">
                <template v-if="!!subWidget.options.labelTooltip">
                  {{subWidget.options.label}}<el-tooltip :content="subWidget.options.labelTooltip" effect="light">
                  <el-icon><component :is="subWidget.options.labelIconClass" /></el-icon></el-tooltip></template>
                <template v-else>
                  {{subWidget.options.label}}<el-icon><component :is="subWidget.options.labelIconClass" /></el-icon></template>
              </template>
            </span>
            <template v-else>
              <span :title="subWidget.options.labelTooltip">{{subWidget.options.label}}</span></template>
          </div>
        </template>
        <!-- <div v-if="!leftActionColumn && !isReadMode" class="action-header-column">
          <span class="action-label">{{i18nt('render.hint.subFormAction')}}</span>
          <el-button v-if="!isReadMode" :disabled="widgetDisabled || actionDisabled || insertDisabled"
                     round type="primary" size="small"
                     class="action-button" @click="addSubFormRow" :title="i18nt('render.hint.subFormAddActionHint')">
            {{i18nt('render.hint.subFormAddAction')}}<svg-icon icon-class="el-plus" /></el-button>
        </div> -->
      </el-row>
      <el-row v-for="(subFormRowId, sfrIdx) in pagedRowIdData" class="sub-form-row" :key="subFormRowId"
        :class="[currentIndex == getSubFormRowIndex(sfrIdx) ? 'active' : '', widget.options.isRowWidth100 ? 'isRowWidth100' : '']"
        @click="selectRowHandle(getSubFormRowIndex(sfrIdx))">
        <!-- 列操作按钮 -->
        <!-- <div v-if="leftActionColumn" class="sub-form-action-column hide-label">
          <div class="action-button-column">
            <el-button :disabled="widgetDisabled || actionDisabled || insertDisabled"
                       circle @click="insertSubFormRow(sfrIdx)"
                       v-show="!isReadMode && !widget.options.appendButtonAtBottom" 
                       :title="i18nt('render.hint.insertSubFormRow')"><svg-icon icon-class="el-plus" /></el-button>
            <el-button :disabled="widgetDisabled || actionDisabled || deleteDisabled"
                       circle @click="deleteSubFormRow(sfrIdx)"
                       v-show="!isReadMode" :title="i18nt('render.hint.deleteSubFormRow')"><svg-icon icon-class="el-delete" /></el-button>
            <span v-if="widget.options.showNumColumn" class="row-number-span">#{{getSubFormRowIndex(sfrIdx)+1}}</span>
          </div>
        </div> -->
        <div v-if="widget.options.showNumColumn" class="row-no-column" :style="{ 'width': widget.options.numColumnWidth }">
          <div class="sub-form-options" v-if="!isReadMode">
            <el-dropdown placement="bottom-end">
              <div class="pointer"><svg-icon icon-class="el-plus" /></div>
              <template #dropdown>
                <el-dropdown-menu>
                  <el-dropdown-item v-if="widget.options.morePermissions.handleAdd"
                    @click.stop="insertSubFormRow(getSubFormRowIndex(sfrIdx) + 1)">新建一行</el-dropdown-item>
                  <el-dropdown-item v-if="widget.options.morePermissions.handleCopy"
                    @click.stop="copySubFormRow(getSubFormRowIndex(sfrIdx))">复制一行</el-dropdown-item>
                  <el-dropdown-item v-if="widget.options.morePermissions.handleDeleteAll"
                    @click.stop="deleteSubFormRow(getSubFormRowIndex(sfrIdx))">删除一行</el-dropdown-item>
                  <el-dropdown-item v-if="!widget.options.isAutoSort && !widget.options.morePermissions.readonly"
                    @click.stop="moveSubFormRow(getSubFormRowIndex(sfrIdx), -1)"
                    :disabled="getSubFormRowIndex(sfrIdx) == 0">上移一行</el-dropdown-item>
                  <el-dropdown-item v-if="!widget.options.isAutoSort && !widget.options.morePermissions.readonly"
                    @click.stop="moveSubFormRow(getSubFormRowIndex(sfrIdx), 1)"
                    :disabled="getSubFormRowIndex(sfrIdx) == rowIdData.length - 1">下移一行</el-dropdown-item>
                </el-dropdown-menu>
              </template>
            </el-dropdown>
          </div>
          <span class="row-number-span">{{getSubFormRowIndex(sfrIdx)+1}}</span>
        </div>
        <template v-if="widget.widgetList && widget.widgetList.length > 0">
          <template v-for="(subWidget, swIdx) in widget.widgetList" :key="swIdx">
            <div v-show="!subWidget.options.hidden"             
              :class="['sub-form-table-column hide-label no-border-top', swIdx === widget.widgetList.length - 1 ? '' : 'no-border-right']"
              :style="{ width: subWidget.options.columnWidth }">
              <div class="sub-form-table-column-content">
                <component :is="getFieldWidget(subWidget.type)" 
                            class="sub-form-table-column-component"
                            :field="fieldSchemaData[getSubFormRowIndex(sfrIdx)][swIdx]"
                            :parent-list="widget.widgetList"
                            :index-of-parent-list="swIdx" :parent-widget="widget"
                            :sub-form-row-id="subFormRowId"
                            :sub-form-row-index="getSubFormRowIndex(sfrIdx)" :sub-form-col-index="swIdx">
                <!-- 子表单暂不支持插槽！！！ -->
                </component>
                <el-button class="sub-form-table-column-button" v-if="isShow(fieldSchemaData[getSubFormRowIndex(sfrIdx)][swIdx], widget)" @click.stop="openDataMappingDialog($event, widget, sfrIdx, fieldSchemaData[getSubFormRowIndex(sfrIdx)][swIdx])">
                  <span title="数据对应关系关联">
                    <svg-icon :icon-class="widget.interMappingIcon" :size="16" color="#2E5CF6" />
                  </span>
                </el-button>
              </div>
              
            </div>
          </template>
          <!-- <div v-if="!leftActionColumn && !isReadMode" class="sub-form-action-column hide-label">
            <div class="action-button-column">
              <el-button :disabled="widgetDisabled || actionDisabled || insertDisabled"
                        circle @click="insertSubFormRow(sfrIdx)"
                        v-show="!isReadMode && !widget.options.appendButtonAtBottom" 
                        :title="i18nt('render.hint.insertSubFormRow')"><svg-icon icon-class="el-plus" /></el-button>
              <el-button :disabled="widgetDisabled || actionDisabled || deleteDisabled"
                        circle @click="deleteSubFormRow(sfrIdx)"
                        v-show="!isReadMode" :title="i18nt('render.hint.deleteSubFormRow')"><svg-icon icon-class="el-delete" /></el-button>
            </div>
          </div> -->
        </template>
        
      </el-row>
      <!-- 表底 -->
      <el-row v-if="widget.widgetFooterList?.length">
        <div class="row-no-column" :style="{ 'width': widget.options.numColumnWidth }" v-if="widget.options.showNumColumn">
          <span class="row-number-span">{{ widget.options.subFormFooterRowTitle }}</span>
        </div>
        <template v-for="(subWidget, swIdx) in widget.widgetFooterList"
          :key="subWidget.id">
          <div v-show="!subWidget.options.hidden"
            :class="['sub-form-table-column hide-label no-border-top', swIdx === widget.widgetFooterList.length - 1 ? '' : 'no-border-right']"
            :style="{ width: subWidget.options.columnWidth }">
            <component :is="subWidget.type + '-widget'"
              :field="subWidget"
              :parent-list="widget.widgetFooterList" :index-of-parent-list="swIdx" :parent-widget="widget"
              :sub-form-row-id="subFormRowId" :sub-form-row-index="0"
              :sub-form-col-index="0"></component>
          </div>
        </template>
      </el-row>
      <!-- 底部新增行按钮 -->
      <!-- <el-row v-if="widget.options.appendButtonAtBottom && !isReadMode && !widget.options.disabled" class="footer-row">
        <el-button type="primary" plain class="sub-form-append-button"
                   :disabled="widgetDisabled || actionDisabled || insertDisabled"
                   @click="addSubFormRow" >
          <el-icon style="margin-right: 6px"><CirclePlus /></el-icon>
          {{i18nt('render.hint.subFormAddRow')}}</el-button>
      </el-row> -->
      <el-row v-if="widget.options.showPagination">
        <el-pagination
            style="margin-top: 8px"
            size="small"
            layout="total, sizes, prev, pager, next"
            :key="paginationKey"
            :background="background"
            :current-page="currentPage || 1"
            :page-sizes="widget.options.pagination.pageSizes"
            :page-size="currentPageSize"
            :total="rowIdData.length"
            @size-change="handlePageSizeChange"
            @current-change="handleCurrentPageChange" />
      </el-row>
    </div>

  </container-item-wrapper>
  <ZHLXSelectFields ref="ZHLXSelectFieldsRef" title="选择导出字段" @ok="onOkBySelectFields" />
</template>

<script>
  import { Delete, Edit, Search, Share, Upload } from '@element-plus/icons-vue'
  import emitter from '@/utils/emitter'
  import eventBus from '@/utils/event-bus'
  import i18n from '@/utils/i18n'
  import { deepClone, generateId } from '@/utils/util'
  import refMixin from '../../../components/form-render/refMixin'
  import ContainerItemWrapper from './container-item-wrapper'
  import containerItemMixin from './containerItemMixin'
  import subformMixin from './subformMixin'
  import FieldComponents from '@/components/form-designer/form-widget/field-widget/index'
  import SvgIcon from '@/components/svg-icon'
  import { broadcastFormulaRecalculateEvent } from "@/utils/formula-util";
  import ZHLXCommonSelect from '@/components/ZHLX-Components/common/commonSelect/index2.vue' // 选人组件
  import ZHLXSelectFields from '@/components/ZHLX-Components/ZHLX-selectFields/index.vue'
  import { TODAY } from '@/utils/formula-util'
  import dayjs from 'dayjs'

  export default {
    name: "sub-form-item",
    componentName: 'ContainerItem',
    mixins: [emitter, i18n, refMixin, containerItemMixin, subformMixin],
    components: {
      ContainerItemWrapper,
      ...FieldComponents,
      SvgIcon,
      ZHLXCommonSelect,
      ZHLXSelectFields
    },
    props: {
      widget: Object,
    },
    provide() {
      return {
        getSubFormFieldFlag: () => true,
        getSubFormName: () => this.widget.options.name,
      }
    },
    inject: ['refList', 'sfRefList', 'globalModel', 'getReadMode', 'getGlobalDsv'],
    data() {
      return {
        rowIdData: [],
        fieldSchemaData: [],
        actionDisabled: false,
        insertDisabled: false,  //是否禁止新增、插入记录
        deleteDisabled: false,  //是否禁止删除记录
        
        currentIndex: null, //当前选中行下标
        pagedRowIdData: [],  //分页后当前所有可见行RowId数组
        currentPage: 1,
        currentPageSize: 10,
        paginationKey: 'pager' + generateId(),
        background: true,
        selectedAuditor: [],
        selectedAuditor: []
      }
    },
    computed: {
      isReadMode() {
        this.currentIndex = null
        return this.getReadMode() || this.widget.options.disabled || this.widget.options.morePermissions.readonly
      },

      leftActionColumn() {
        //return (this.widget.options.actionColumnPosition || 'left') === 'left'

        let showFlag = (this.widget.options.actionColumnPosition || 'left') === 'left'
        showFlag = showFlag && (this.widget.options.showNumColumn || !this.widget.options.appendButtonAtBottom)
        return showFlag
      },

      widgetDisabled() {
        return !!this.widget.options.disabled
      },

      disabledClass() {
        return !!this.widget.options.disabled ? 'sub-form-disabled' : ''
      },

      readModeClass() {
        return !!this.getReadMode() ? 'sub-form-read-mode' : ''
      },
      customClass() {
        return this.widget.options.customClass || ''
      },
    },
    created() {
      this.initRefList()
      this.registerSubFormToRefList()

      this.initRowIdData(true)
      if (!this.widget.options.showPagination) {
        this.pagedRowIdData = this.rowIdData
      } else {
        this.currentPage = 1
        this.currentPageSize = this.widget.options.pagination.pageSize
        this.sliceRowIdData()
      }
      
      this.initFieldSchemaData(true)
      this.initEventHandler()

      this.handleOnCreated()
    },
    mounted() {
      this.handleSubFormFirstRowAdd()  //默认添加首行后，主动触发相关事件！！

      this.handleOnCreated()
    },
    beforeUnmount() {
      this.unregisterFromRefList()
    },
    methods: {
      /******************** 原有代码 start ********************/
      // 如有新增功能代码，须在最下方自定义代码处增加

      getLabelAlign(widget, subWidget) {
        return subWidget.options.labelAlign || widget.options.labelAlign
      },

      registerSubFormToRefList() {
        if (this.widget.type === 'sub-form') {
          this.sfRefList[this.widget.options.name] = this
        }
      },

      initRowIdData(initFlag) {
        if (this.widget.type === 'sub-form') {
          this.rowIdData.splice(0, this.rowIdData.length)  //清除数组必须用splice，length=0不会响应式更新！！
          let subFormModel = this.formModel[this.widget.options.name]
          if (!!subFormModel && (subFormModel.length > 0)) {
            subFormModel.forEach(() => {
              this.rowIdData.push('id' + generateId())
            })

            if (!this.widget.options.showPagination) {
              this.pagedRowIdData = this.rowIdData
            } else {
              this.sliceRowIdData()
            }

            if (!!initFlag) {
              //注意：事件触发需延期执行，SumFormDataChange事件处理代码中可能存在尚未创建完成的组件！！
              setTimeout(() => {
                this.handleSubFormRowChange(subFormModel)
              }, 800)
            }
          }
        }
      },

      addToRowIdData() {
        const newRowId = 'id' + generateId()
        this.rowIdData.push(newRowId)
        if (this.widget.options.showPagination) {
          this.pagedRowIdData.push(newRowId)
        }
      },

      insertToRowIdData(rowIndex, pagedRowIndex) {
        const newRowId = 'id' + generateId()
        this.rowIdData.splice(rowIndex, 0, newRowId)
        if (this.widget.options.showPagination) {
          this.pagedRowIdData.splice(pagedRowIndex, 0, newRowId)
        }
      },

      deleteFromRowIdData(rowIndex, pagedRowIndex) {
        this.rowIdData.splice(rowIndex, 1)
        if (this.widget.options.showPagination && (pagedRowIndex !== undefined)) {
          this.pagedRowIdData.splice(pagedRowIndex, 1)
        }
      },

      getRowIdData() {
        return this.rowIdData
      },

      getWidgetRefOfSubForm(widgetName, rowIndex) {
        let realWidgetName = widgetName + '@row' + this.rowIdData[rowIndex]
        return this.getWidgetRef(realWidgetName)
      },

      initFieldSchemaData(initFlag) {  //初始化fieldSchemaData！！！
        if (this.widget.type !== 'sub-form') {
          return
        }

        let rowLength = this.rowIdData.length || 1  //至少生成一个数组元素！！
        if (!initFlag) {
          //rowLength = this.rowIdData.length
        }
        this.fieldSchemaData.splice(0, this.fieldSchemaData.length)  //清除数组必须用splice，length=0不会响应式更新！！
        if (rowLength > 0) {
          for (let i = 0; i < rowLength; i++) {
            let fieldSchemas = []
            this.widget.widgetList.forEach(swItem => {
              fieldSchemas.push( this.cloneFieldSchema(swItem) )
            })
            this.fieldSchemaData.push(fieldSchemas)
          }
        }
      },

      addToFieldSchemaData(rowIndex) {
        let fieldSchemas = []
        this.widget.widgetList.forEach(swItem => {
          fieldSchemas.push( this.cloneFieldSchema(swItem) )
        })

        if (rowIndex === undefined) {
          this.fieldSchemaData.push(fieldSchemas)
        } else {
          this.fieldSchemaData.splice(rowIndex, 0, fieldSchemas)
        }
      },

      deleteFromFieldSchemaData(rowIndex) {
        this.fieldSchemaData.splice(rowIndex, 1)
      },

      cloneFieldSchema(fieldWidget) {
        let newFieldSchema = deepClone(fieldWidget)
        newFieldSchema.id = fieldWidget.type + generateId()
        newFieldSchema.oid = fieldWidget.id  //重要：保留原始id!!
        return newFieldSchema
      },

      initEventHandler() {
        if (this.widget.type !== 'sub-form') {
          return
        }

        this.on$('setFormData', (params) => {
          const newFormData = params[0], disableChangeEvent = params[1]
          this.initRowIdData(false)
          if (!this.widget.options.showPagination) {
            this.pagedRowIdData = this.rowIdData
          } else {
            this.currentPage = 1
            this.currentPageSize = this.widget.options.pagination.pageSize
            this.sliceRowIdData()
          }
          
          this.initFieldSchemaData(false)

          let subFormData = newFormData[this.widget.options.name] || []
          setTimeout(() => {  //延时触发SubFormRowChange事件, 便于更新计算字段！！
            this.handleSubFormRowChange(subFormData)

            //触发计算公式重新计算
            this.recalculateFormula()
          }, 800)
        })
      },

      handleSubFormFirstRowAdd() {
        if (this.widget.type !== 'sub-form') {
          return
        }

        if (!!this.widget.options.showBlankRow && (this.rowIdData.length === 1)) {
          let oldSubFormData = this.formModel[this.widget.options.name] || []

          //确认组件创建成功后触发事件!!
          this.$nextTick(() => {
            this.handleSubFormRowAdd(oldSubFormData, this.rowIdData[0])
            this.handleSubFormRowChange(oldSubFormData)

            if (!!this.widget.options.disabled) {
              this.disableSubForm()
            }
          })
        }
      },

      addSubFormRow() {
        let newSubFormDataRow = {}
        this.widget.widgetList.forEach(subFormItem => {
          if (!!subFormItem.formItemFlag) {
            let fieldKeyName = subFormItem.options.name
            fieldKeyName = subFormItem.options.keyNameEnabled ? (subFormItem.options.keyName || fieldKeyName) : fieldKeyName
            newSubFormDataRow[fieldKeyName] = subFormItem.options.defaultValue
          }
        })

        let oldSubFormData = this.formModel[this.widget.options.name] || []
        if (!this.widget.options.showPagination) {
          oldSubFormData.push(newSubFormDataRow)
        } else {
          //插入在当前分页的最后位置！！
          //const newRowIndex = this.currentPage * this.currentPageSize
          const newRowIndex = (this.currentPage - 1) * this.currentPageSize +  this.pagedRowIdData.length
          oldSubFormData.splice(newRowIndex, 0, newSubFormDataRow)
        }
        this.addToRowIdData()
        this.addToFieldSchemaData()

        this.$nextTick(() => {
          this.handleSubFormRowAdd(oldSubFormData, this.rowIdData[oldSubFormData.length - 1])
          this.handleSubFormRowChange(oldSubFormData)
          // 子表单校验新增行
          this.validSubFormRow(oldSubFormData.length - 1)
          //触发计算公式重新计算！！
          broadcastFormulaRecalculateEvent(this, oldSubFormData.length - 1)
        })
      },

      /**
     * 插入一行
     * @param {*} beforeFormRowIndex 当前操作行
     */
      insertSubFormRow(beforeFormRowIndex) {
        const realSFRowIndex = this.getSubFormRowIndex(beforeFormRowIndex)
        let newSubFormDataRow = {}
        this.widget.widgetList.forEach(subFormItem => {
          if (!!subFormItem.formItemFlag) {
            let fieldKeyName = subFormItem.options.name
            fieldKeyName = subFormItem.options.keyNameEnabled ? (subFormItem.options.keyName || fieldKeyName) : fieldKeyName
            newSubFormDataRow[fieldKeyName] = subFormItem.options.defaultValue
          }
        })

        let oldSubFormData = this.formModel[this.widget.options.name] || []
        oldSubFormData.splice(realSFRowIndex, 0, newSubFormDataRow)
        this.insertToRowIdData(realSFRowIndex, beforeFormRowIndex)
        this.addToFieldSchemaData(realSFRowIndex)

        this.$nextTick(() => {
          this.handleSubFormRowInsert(oldSubFormData, this.rowIdData[realSFRowIndex])
          this.handleSubFormRowChange(oldSubFormData)
          // 子表单校验新增行
          this.validSubFormRow(beforeFormRowIndex)
          //触发计算公式重新计算！！
          broadcastFormulaRecalculateEvent(this, beforeFormRowIndex)
        })
      },

      /**
       * 删除最后一行（注意：此方法未考虑子表单的分页！！）
       */
      deleteSubFormLastRow() {
        const lastRowIndex = this.rowIdData.length - 1
        let oldSubFormData = this.formModel[this.widget.options.name] || []
        let deletedDataRow = deepClone(oldSubFormData[lastRowIndex])
        oldSubFormData.splice(lastRowIndex, 1)
        this.deleteFromRowIdData(lastRowIndex)
        this.deleteFromFieldSchemaData(lastRowIndex)

        //确认组件创建成功后触发事件!!
        this.$nextTick(() => {
          this.handleSubFormRowDelete(oldSubFormData, deletedDataRow, lastRowIndex)
          this.handleSubFormRowChange(oldSubFormData)

          //触发计算公式重新计算！！
          broadcastFormulaRecalculateEvent(this, formRowIndex)
        })
      },

      handleSubFormRowChange(subFormData) {
        if (!!this.widget.options.onSubFormRowChange) {
          let customFunc = new Function('subFormData', this.widget.options.onSubFormRowChange)
          customFunc.call(this, subFormData)
        }
      },

      handleSubFormRowAdd(subFormData, newRowId) {
        if (!!this.widget.options.onSubFormRowAdd) {
          let customFunc = new Function('subFormData', 'newRowId', this.widget.options.onSubFormRowAdd)
          customFunc.call(this, subFormData, newRowId)
        }
      },

      handleSubFormRowInsert(subFormData, newRowId) {
        if (!!this.widget.options.onSubFormRowInsert) {
          let customFunc = new Function('subFormData', 'newRowId', this.widget.options.onSubFormRowInsert)
          customFunc.call(this, subFormData, newRowId)
        }
      },

      handleSubFormRowDelete(subFormData, deletedDataRow, deletedRowIndex) {
        if (!!this.widget.options.onSubFormRowDelete) {
          let customFunc = new Function('subFormData', 'deletedDataRow', 'deletedRowIndex', this.widget.options.onSubFormRowDelete)
          customFunc.call(this, subFormData, deletedDataRow, deletedRowIndex)
        }
      },

      setDisabled(flag) {
        this.widget.options.disabled = flag
        if (!!flag) {
          this.disableSubForm()
        } else {
          this.enableSubForm()
        }
      },

      /**
       * 设置单行子表单是否禁止新增、插入记录
       * @param flag
       */
      setInsertDisabled(flag) {
        this.insertDisabled = flag
      },

      /**
       * 设置单行子表单是否禁止删除记录
       * @param flag
       */
      setDeleteDisabled(flag) {
        this.deleteDisabled = flag
      },

      /**
       * 单独给子表单赋值
       * 注意：该方法仅触发组件的onChange事件以及子表单的onFormRowChange事件，不会触发表单的onFormDataChange等其他事件！！
       * @param subFormValues
       */
      setSubFormValues(subFormValues, needValidation = true) {
        this.globalModel.formModel[this.widget.options.name] = subFormValues
        this.initRowIdData(false)
        this.initFieldSchemaData(false)
        // 处理合计行反显数据
        if (this.widget.widgetFooterList?.length) {
          this.widget.widgetFooterList?.forEach(item => {
            item.options.defaultValue = subFormValues[0]?.[item.options.name]
          })
        }

        // 校验子表单数据行
        if (needValidation && subFormValues && subFormValues.length) {
          subFormValues.forEach((item, index) => {
            this.validSubFormRow(index)
          })
        }

        if (!this.widget.options.showPagination) {
          this.pagedRowIdData = this.rowIdData
        } else {
          this.currentPage = 1
          this.sliceRowIdData()
        }

        setTimeout(() => {  //延时触发SubFormRowChange事件, 便于更新计算字段！！
          this.handleSubFormRowChange(subFormValues)

          //刷新子表单计算公式重新计算
          if (this.widget.options.showPagination) {
            this.recalculateFormula()
          }
        }, 800)
      },

      /**
       * 单独为子表单某行的字段组件赋值
       * @param fieldName
       * @param fieldValue
       * @param rowIndex
       */
      setSubFormFieldValue(fieldName, fieldValue, rowIndex) {
        const subFormData = this.globalModel.formModel[this.widget.options.name]
        subFormData[rowIndex][fieldName] = fieldValue

        this.handleSubFormRowChange(subFormData)
      },

      /* 强制刷新跟子表单相关的公式重新计算 */
      recalculateFormula() {
        broadcastFormulaRecalculateEvent(this)
      },

      getSubFormRowIndex(index) {
        if (!this.widget.options.showPagination) {
          return index
        } else {
          return (this.currentPage - 1) * this.currentPageSize + index
        }
      },

      /**
       * 根据当前页码和每页大小，对 `rowIdData` 进行分页切片，并将结果存储在 `pagedRowIdData` 中。
       * 
       * 该函数通过计算当前页的起始索引，使用 `slice` 方法从 `rowIdData` 中提取出当前页的数据，
       * 并将其赋值给 `pagedRowIdData`，用于在页面上显示分页后的数据。
       * 
       * @returns {void} 无返回值
       */
      sliceRowIdData() {
        // 计算当前页的起始索引
        const pageStart = (this.currentPage - 1 ) * this.currentPageSize

        // 对 `rowIdData` 进行切片，获取当前页的数据，并赋值给 `pagedRowIdData`
        this.pagedRowIdData = this.rowIdData.slice(pageStart, pageStart + this.currentPageSize)
      },
      
      //校验当前显示的所有子表单内部组件合法性，返回Promise<Boolean>
      validatePagedSubFields() {
        if (this.pagedRowIdData.length <= 0) {
          return new Promise((resolve) => {
            resolve(true)
          })
        }
        
        const subFieldsArray = []
        this.pagedRowIdData.forEach(rowId => {
          this.widget.widgetList.forEach(sw => {
            if (sw.formItemFlag) {
              const swRef = this.getWidgetRef(sw.options.name + '@row' + rowId)
              if (swRef && swRef.getPropName) {
                subFieldsArray.push(swRef.getPropName())
              }
            }
          })
        })
        
        if (subFieldsArray.length > 0) {
          return this.getFormRef().getNativeForm().validateField(subFieldsArray)
        } else {
          return new Promise((resolve) => {
            resolve(true)
          })
        }
      },
      
      /* 重新生成分页组件 */
      refreshPagination() {
        this.paginationKey = 'pager' + generateId()
      },
      
      handlePageSizeChange(pageSize) {
        this.validatePagedSubFields().then(pass => {
          if (pass) {
            this.currentPage = 1
            this.currentPageSize = pageSize
            this.widget.options.pagination.pageSize = pageSize
            this.sliceRowIdData()
          } else {
            this.refreshPagination()
            this.$message.error(this.i18nt("render.hint.subFormValidationFailed"))
          }
        }).catch(err => {
          this.refreshPagination()
          this.$message.error(this.i18nt("render.hint.subFormValidationFailed"))
        })
      },

      handleCurrentPageChange(currentPage) {
        this.validatePagedSubFields().then(pass => {
          if (pass) {
            this.currentPage = currentPage
            this.sliceRowIdData()
          } else {
            this.$message.error(this.i18nt("render.hint.subFormValidationFailed"))
          }
        }).catch(err => {
          this.$message.error(this.i18nt("render.hint.subFormValidationFailed"))
        })
      },

      
      /******************** 原有代码 end ********************/

      
      /******************** 自定义代码 start ********************/
      /**
       * 双击节点
       * @param {*} sfrIdx 下标
       */
      selectRowHandle(sfrIdx) {
        if (this.isReadMode) { return; }
        this.currentIndex = sfrIdx;
      },

      sortSubForm() {
        let sortBy = this.widget.options.subAutoSortCode;
        if (!this.widget.options.isAutoSort || !sortBy.sortCode) {
          return;
        }
        if (!sortBy) {
          this.$message.info('未配置排序规则');
          return;
        }
        let oldSubFormData = this.formModel[this.widget.options.name] || []
        // 创建一个映射数组，用于保存原始索引
        let map = Array.from({ length: oldSubFormData.length }, (_, i) => i);
        map.sort((a, b) => {
          // isFinite(number) 如果 number 是有限数字（或可转换为有限数字），那么返回 true。否则，如果 number 是 NaN（非数字），或者是正、负无穷大的数，则返回 false。  
          const c = oldSubFormData[a][sortBy.sortCode], d = oldSubFormData[b][sortBy.sortCode];
          return isFinite(c) && isFinite(d) ? (c - d) : c.localeCompare(d)
        });
        oldSubFormData = map.map(index => oldSubFormData[index]);
        if (sortBy.sortBy != 1) {
          oldSubFormData.reverse();
        }
        this.formModel[this.widget.options.name] = oldSubFormData;
        this.initRowIdData(true)
        this.currentIndex = null;
      },

      
      /**
       * 复制一行到指定位置 默认为下一行
       * @param {*} beforeFormRowIndex 当前操作行
       * @param {*} targetFormRowIndex 目标行
       * @param {*} needValidation 是否校验 默认校验
       */
      copySubFormRow(beforeFormRowIndex, targetFormRowIndex = beforeFormRowIndex + 1, needValidation = true) {
        if (beforeFormRowIndex == null) {
          this.$message.error('请先选择数据行');
          return;
        }
        let oldSubFormData = this.formModel[this.widget.options.name] || [];
        let newSubFormDataRow = deepClone(oldSubFormData[beforeFormRowIndex]);
        // 底表判断
        if (this.widget.widgetFooterList?.length) {
          const widgetFooterMap = this.widget.widgetFooterList?.map(i => i.options.name);
          if (beforeFormRowIndex == 0) {
            widgetFooterMap.forEach(i => {
              delete newSubFormDataRow[i]
            });
          } else if (targetFormRowIndex == 0) {
            widgetFooterMap.forEach(i => {
              delete oldSubFormData[beforeFormRowIndex][i]
            });
          }
        }
        oldSubFormData.splice(targetFormRowIndex, 0, newSubFormDataRow);
        this.insertToRowIdData(targetFormRowIndex);
        this.addToFieldSchemaData(targetFormRowIndex);

        this.$nextTick(() => {
          this.handleSubFormRowInsert(oldSubFormData, this.rowIdData[targetFormRowIndex]);
          this.handleSubFormRowChange(oldSubFormData);
          // 新增行数据校验
          if (needValidation) {
            this.validSubFormRow(targetFormRowIndex)
          }
          //触发计算公式重新计算！！
          broadcastFormulaRecalculateEvent(this, targetFormRowIndex)
        })
      },

      /**
       * 移动一行
       * @param {*} beforeFormRowIndex 当前操作行
       * @param {*} direction -1上 1下
       */
      moveSubFormRow(beforeFormRowIndex, direction) {
        const targetFormRowIndex = beforeFormRowIndex + (direction > 0 ? direction + 1 : direction);
        this.copySubFormRow(beforeFormRowIndex, targetFormRowIndex, false);
        const delIndex = direction > 0 ? beforeFormRowIndex : beforeFormRowIndex - direction;
        this.deleteSubFormRow(delIndex, true);
        this.currentIndex = beforeFormRowIndex + direction;
        this.validSubFormRow(this.currentIndex)
      },

      /**
       * 删除一行
       */
      deleteSubFormRow(formRowIndex, hideConfirm = false) {
        if (formRowIndex == null) {
          this.$message.error('请先选择数据行');
          return;
        }
        const realSFRowIndex = this.getSubFormRowIndex(formRowIndex)
        this.$confirm(this.i18nt('render.hint.deleteSubFormRow') + '?', this.i18nt('render.hint.prompt'), {
          confirmButtonText: this.i18nt('render.hint.confirm'),
          cancelButtonText: this.i18nt('render.hint.cancel')
        }).then(() => {
          let oldSubFormData = this.formModel[this.widget.options.name] || []
          let deletedDataRow = deepClone(oldSubFormData[realSFRowIndex])
          oldSubFormData.splice(realSFRowIndex, 1)
          this.deleteFromRowIdData(realSFRowIndex, formRowIndex)
          this.deleteFromFieldSchemaData(realSFRowIndex)

          this.$nextTick(() => {
            this.handleSubFormRowDelete(oldSubFormData, deletedDataRow, realSFRowIndex)
            this.handleSubFormRowChange(oldSubFormData)

            //触发计算公式重新计算！！
            broadcastFormulaRecalculateEvent(this)
          })
        }).catch(() => {
          //
        })
      },

       /**
       * 删除所有行
       */
      delAllSubFormRow() {
        this.$confirm('确定要删除所有行?', this.i18nt('render.hint.prompt'), {
          confirmButtonText: this.i18nt('render.hint.confirm'),
          cancelButtonText: this.i18nt('render.hint.cancel')
        }).then(() => {
          this.rowIdData.splice(0, this.rowIdData.length);
          this.fieldSchemaData.splice(0, this.fieldSchemaData.length);
          let oldSubFormData = this.formModel[this.widget.options.name] || [];
          oldSubFormData.splice(0, oldSubFormData.length);
          this.$nextTick(() => {
            this.handleSubFormRowDelete(oldSubFormData);
            this.handleSubFormRowChange(oldSubFormData);
            //触发计算公式重新计算！！
            broadcastFormulaRecalculateEvent(this);
            this.currentIndex = null;
          })
        })
      },

      
      /**
       * 将二维数组导出为CSV文件并下载
       * @param {Array<Array<string>>} data - 要导出的二维数组
       * @param {string} filename - 导出的CSV文件名
       */
      exportToCSV(data, filename) {
        // 转换数组中的每一行数据为CSV格式
        const csvContent = data.map(row =>
          row.map(item => {
            // 处理包含逗号、回车或双引号的内容
            if (item.includes(',') || item.includes('\n') || item.includes('"')) {
              // 将双引号替换为两个双引号，并包裹在双引号内
              item = `"${item.replace(/"/g, '""')}"`;
            }
            return item;
          }).join(',')
        ).join('\n');
        // 确保使用UTF-8 BOM防止中文乱码
        const bom = '\uFEFF';
        const csvData = bom + csvContent;
        // 创建一个Blob对象并指定MIME类型
        const blob = new Blob([csvData], { type: 'text/csv;charset=utf-8;' });
        // 创建一个下载链接
        const link = document.createElement('a');
        if (link.download !== undefined) {
          // 设置下载文件名
          link.href = URL.createObjectURL(blob);
          link.download = filename;
          link.style.visibility = 'hidden';

          // 触发下载
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        }
      },

      exportSubForm(columnIds) {
        try {
          let data = Array.isArray(this.formModel[this.widget.id]) ? this.formModel[this.widget.id].map((item, i) => {
            const cell = {};
            if (this.widget.options.showNumColumn) cell['index'] = i + 1;
            for (const k in item) {
              const fieldWidget = this.widget.widgetList.find(field => field.options.name == k)
              if (!fieldWidget || fieldWidget.options.hidden) {
                continue;
              }
              let defaultValue = deepClone(item[k]);
              cell[fieldWidget.id] = "";
              if (fieldWidget.type === 'select-unit' && this.isJSON(defaultValue)) {
                defaultValue = JSON.parse(defaultValue);
              }
              if (fieldWidget.type !== "serial-number" && (defaultValue === null || defaultValue === "" || defaultValue === undefined || Array.isArray(defaultValue) && !defaultValue.length)) {
                cell[fieldWidget.id] = "";
              } else if (Array.isArray(defaultValue) && defaultValue.length && !fieldWidget.type.includes('-range')) {
                defaultValue.map((value, index) => {
                  cell[fieldWidget.id] += this.createNewData(value, fieldWidget.type, fieldWidget.options, defaultValue.length - index - 1);
                })
              } else {
                cell[fieldWidget.id] = this.createNewData(defaultValue, fieldWidget.type, fieldWidget.options);
              }
            }
            return cell
          }) : []
          let column = columnIds.map(columnId => {
            const findColumn = this.widget.widgetList.find(item => item.options.name == columnId)
            if (findColumn) {
              return {
                'name': findColumn.options.name,
                'label': findColumn.options.label
              }
            }
            return
          }).filter(item => !!item)
          if (this.widget.widgetFooterList?.length && Array.isArray(this.formModel[this.widget.id])) {
            let footerData = data[data.length] = {}
            this.widget.widgetFooterList.forEach((item, index) => {
              footerData[column[index].name] = this.formModel[this.widget.id][0][item.options.name].toString()
            })
            footerData['index'] = this.widget.options.subFormFooterRowTitle
          }
          // if (this.widget.options.showNumColumn) column.unshift({ 'name': 'index', 'label': '序号' })
          // console.log('getGlobalDsv', this.getGlobalDsv().userInfo)
          const {name, username} = this.getGlobalDsv()?.userInfo || {}
          const excelName = [this.widget.options.label, (name || username || ''), TODAY()].filter(item => item).join('-')
          this.exportExcel(
            column,
            data,
            excelName,
            'xlsx'
          )
        } catch (e) {
          console.log('导出excel失败', e)
        }
      },
      
      /**
       * 判断是否是json字符串
       */
      isJSON(str) {
        try {
          JSON.parse(str);
        } catch (e) {
          return false;
        }
        return true;
      },

      /**
       * 创建统一字段对象
       * @param value 组件对应数组
       * @param type 组件类型
       * @param options 组件配置
       * @param step 剩余循环步数
       */
      createNewData(value, type, options, step = 0) {
        let zhlx_gjz_label = value
        if (!(type === 'select' || type === 'radio' || type === 'checkbox' || type ==='date')) {
          if (!value || Array.isArray(value) && !value.length || typeof value !== "object") {
            return zhlx_gjz_label.toString();
          }
        }
        if (type === 'file-list') { // 附件列表
          zhlx_gjz_label = value.originalFilename + (step == 0 ? "" : "、");
        } else if (type === 'select-unit') { // 抄送组件
          zhlx_gjz_label = value.name + value.append;
        } else if (type.includes('select-')) { // 选人组件
          zhlx_gjz_label = value.mainName + (step == 0 ? "" : "、");
        } else if (type === 'process-comments') { // 流程意见
          zhlx_gjz_label = value.handleOpinion;
        } else if (type === 'select' || type === 'radio' || type === 'checkbox') { // 下拉/单选框/多选框
          const selectData = options.optionItems.find(select => select.value == value);
          if (!!selectData) {
            zhlx_gjz_label = selectData.label + (step == 0 ? "" : "、");
          }
        } else if (type === 'time-range') { // 时间范围/日期范围
          zhlx_gjz_label = Array.isArray(value) ? value.join('~') : value.toString();
        } else if (type === 'date') {
          zhlx_gjz_label = value ? dayjs(value).format(options.format) : ''
        } else if (type === 'date-range') {
          zhlx_gjz_label = Array.isArray(value) ? value.map(val => dayjs(val).format(options.format)).join('~') : value.toString();
        }
        return zhlx_gjz_label;
      },

      batchPaddingHandle() {
        this.$refs.zhlxCommonSelectRef.openDialog();
      },
      openDataMappingDialog($event, widget, index, item) {
        console.log('subform open data mapping dialog')
        this.getGlobalDsv().openDataMappingDialog($event, widget, index, item)
      },
      async exportExcel(column, data, filename, format) {
        // 创建excel
        const workbook = new ExcelJS.Workbook();
        // 设置信息
        workbook.creator = "Me";
        workbook.title = filename;
        workbook.created = new Date();
        workbook.modified = new Date();
        // 创建工作表
        const worksheet = workbook.addWorksheet(filename);
        // 设置列名
        let columnsName = [];
        console.log(column, 'column')
        column.forEach((item, index) => {
          let maxLength = 0;
          data.map(cell => {
            let columnLength = cell[item.name] ? cell[item.name].toString().length : 10;
            if (columnLength > maxLength ) {
              maxLength = columnLength;
            }
          })
          let obj = {
            header: item.label, key: item.name, width: maxLength < 10 ? 10 : maxLength
          }
          // 设置列名、键和宽度
          columnsName.push(obj);
        })
        worksheet.columns = columnsName;
        // 添加行
        worksheet.addRows(data);
        // 写入文件

        const uint8Array =
          format === "xlsx"
            ? await workbook.xlsx.writeBuffer()
            : await workbook.csv.writeBuffer();

        const blob = new Blob([uint8Array], { type: "application/octet-binary" });
        if (window.navigator.msSaveOrOpenBlob) {
          // msSaveOrOpenBlob方法返回boolean值
          navigator.msSaveBlob(blob, filename + `.${format}`);
          // 本地保存
        } else {
          const link = document.createElement("a"); // a标签下载
          link.href = window.URL.createObjectURL(blob); // href属性指定下载链接
          link.download = filename + `.${format}`; // dowload属性指定文件名
          link.click(); // click()事件触发下载
          window.URL.revokeObjectURL(link.href); // 释放内存
        }
      },

      exportSubFormCsv() {
        let data = this.formModel[this.widget.id].map(item => {
          const arr = []
          for (const k in item) {
            arr.push((item[k] == 0 || item[k]) ? item[k].toString() : '')
          }
          return arr
        })
        const formHeader = this.widget.widgetList.map(item => item.options.label)
        data.unshift(formHeader)
        this.exportToCSV(data, 'output.csv');
      },

      // 已选审批对象改变后的回调
      handleSelectedAuditorChange(ids, records) {
        const personName = this.widget.widgetList.filter(item => item.type === 'select-person')[0].id;
        const rowIndex = this.rowIdData.length
        records.forEach(async (item, index) => {
          await this.addSubFormRow();
          personName && this.getWidgetRefOfSubForm(personName, rowIndex + index).onUserUpdate([item.mainId], [item])
        })

      },

      isShow(item, weight) {
        const name = item.options.name || item.options.keyName;
        const filedList = weight.filedList || [];
        return filedList.find((v) => v.sourceFileId === name);
      },

      onOkBySelectFields(data) {
        this.exportSubForm(data)
      },


      /******************** 自定义代码 end ********************/

    },
  }
</script>

<style lang="scss">
.rowBtnContent {
  display: grid;

  .el-button {
    width: 120px;
    margin-bottom: 12px;
    margin-left: 0;
  }
}

.isRowWidth100 {
  width: 100% !important;
}
</style>
<style lang="scss" scoped>
  .no-border-right {
    border-right: 0px !important;
  }

  .no-border-top {
    border-top: 0px !important;
  }

  .sub-form-container {
    margin-bottom: 8px;
    text-align: left; //IE浏览器强制居左对齐
    overflow-x: auto; //配合max-content属性，超出自动显示水平滚动条
    padding-top: 8px !important;
    padding-bottom: 8px !important;

    .options-row {
      margin-bottom: 8px !important;
      padding: 0 !important;
      flex-wrap: nowrap;
    }

    :deep(.el-row.header-row) {
      padding: 0;
      width: max-content;
    }

    :deep(.el-row.sub-form-row) {
      padding: 0;
      width: max-content;

      &.active {
        background: #e8f3fd;

        // .sub-form-options {
        //   display: block;
        // }
      }

      .sub-form-options {
        margin-right: 4px;
      }
    }
  }

  div.action-header-column {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 120px;
    border: 1px solid #e1e2e3;
    background: #f1f2f3;
    padding: 8px;

    .action-label {
      margin-right: 12px;
    }

    .action-button {
      padding-left: 8px;
      padding-right: 8px;
    }
  }

  div.row-no-header-column {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    text-align: center;
    border: 1px solid #e1e2e3;
    background: #f1f2f3;
    border-right: 0px;
    box-sizing: border-box;
  }

  div.field-header-column {
    display: flex;
    align-items: center;
    justify-content: center;
    //overflow: hidden;
    //white-space: nowrap;  //文字超出长度不自动换行
    //text-overflow: ellipsis;  //文字超出长度显示省略号
    border: 1px solid #e1e2e3;
    background: #f1f2f3;
    padding: 8px;
    box-sizing: border-box;
    span.custom-label i {
      margin: 0 3px;
    }
  }

  div.field-header-column.is-required:before {
    content: '*';
    color: #F56C6C;
    margin-right: 4px;
  }

  div.label-center-left {
    text-align: left;
  }

  div.label-center-align {
    text-align: center;
  }

  div.label-right-align {
    text-align: right;
  }

  div.sub-form-action-column {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 120px;
    border: 1px solid #e1e2e3;
    padding: 8px;

    :deep(.el-form-item) {
      margin-bottom: 0;
    }

    :deep(.el-button) {
      font-size: 14px;
      padding: 0;
      background: #DCDFE6;
      border: 4px solid #DCDFE6;
    }

  }

  div.sub-form-action-column.hide-label {
    :deep(.el-form-item__label) {
      display: none;
    }
  }

  div.row-no-column {
    display: flex;
    align-items: center;
    width: 50px;
    border: 1px solid #e1e2e3;
    justify-content: center;
    border-right: 0px;
    border-top: 0px;
    box-sizing: border-box;
  }

  div.sub-form-table-column {
    display: inline-block;
    border: 1px solid #e1e2e3;
    padding: 4px 8px;
    box-sizing: border-box;

    :deep(.el-form-item) {
      margin-left: 4px;
      margin-right: 4px;
      margin-bottom: 0;
    }

    :deep(.el-form-item__content) {
      margin-left: 0 !important;
    }
  }

  div.sub-form-table-column.hide-label {
    :deep(.el-form-item__label) {
      display: none;
    }
  }

  .sub-form-table-column-content {
    display: flex;
    align-items: center;
  }
  .sub-form-table-column-component {
    flex:1;
  }
  .sub-form-table-column-content .sub-form-table-column-button.el-button {
    height: 28px !important;
    padding: 0 5px !important;
  }

  .footer-row {
    display: block;
    text-align: center;

    .sub-form-append-button {
      margin-top: 8px;
      width: 30%;
    }
  }

</style>
